﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using YArchitech.Revit.RevitExtension;
using YJKRGeometry;

namespace HangerSupport
{
	public class DrawingPlotter
	{
		public DrawingPlotter(System.Windows.Forms.Control control, Graphics graphics, List<CurveInfo> curves)
		{
			this.m_Control = control;
			this.m_Graphics = graphics;
			this.m_Curves = curves;
		}

		public DrawingPlotter(System.Windows.Forms.Control control, Graphics graphics, List<TextNoteInfo> textNotes)
		{
			this.m_Control = control;
			this.m_Graphics = graphics;
			this.m_TextNotes = textNotes;
		}

		public DrawingPlotter(System.Windows.Forms.Control control, Graphics graphics, List<CurveInfo> curves, List<TextNoteInfo> textNotes)
		{
			this.m_Control = control;
			this.m_Graphics = graphics;
			this.m_Curves = curves;
			this.m_TextNotes = textNotes;
		}

		public DrawingPlotter(System.Windows.Forms.Control control, Graphics graphics, List<CurveInfo> curves, List<TextNoteInfo> textNotes, List<FillRegion> fillRegions)
		{
			this.m_Control = control;
			this.m_Graphics = graphics;
			this.m_Curves = curves;
			this.m_TextNotes = textNotes;
			this.m_FillRegions = fillRegions;
		}

		public void Draw()
		{
			bool flag = this.m_Curves.Count < 1 && this.m_TextNotes.Count < 1 && this.m_FillRegions.Count < 1;
			if (!flag)
			{
				this.m_Graphics.SmoothingMode = SmoothingMode.HighQuality;
				this.m_Graphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
				this.m_Graphics.Clear(System.Drawing.Color.White);
				Size size = this.m_Control.Size;
				Size size2 = new Size((int)(0.9 * (double)size.Width), (int)(0.9 * (double)size.Height));
				Transform trans = this.ComputerTransMatrix(size2);
				foreach (FillRegion fillRegion in this.m_FillRegions)
				{
					this.DrawFillRegion(fillRegion, trans);
				}
				foreach (CurveInfo curveInfo in this.m_Curves)
				{
					Pen penWithCurveInfo = this.GetPenWithCurveInfo(curveInfo.Color, curveInfo.LineWidth * this.GetScale(size2));
					Line line = curveInfo.CurveObj as Line;
					bool flag2 = null != line;
					if (flag2)
					{
						this.DrawLine(penWithCurveInfo, line, trans);
					}
					else
					{
						Arc arc = curveInfo.CurveObj as Arc;
						bool flag3 = null != arc;
						if (flag3)
						{
							this.DrawArc(penWithCurveInfo, arc, trans);
						}
					}
				}
				foreach (TextNoteInfo textNoteInfo in this.m_TextNotes)
				{
					this.DrawText(textNoteInfo, trans);
				}
			}
		}

		protected Pen GetPenWithCurveInfo(PenColor penColor, float lineWidth)
		{
			System.Drawing.Color color = this.PenColorToColor(penColor);
			return new Pen(color, lineWidth);
		}

		protected System.Drawing.Color PenColorToColor(PenColor penColor)
		{
			System.Drawing.Color white = System.Drawing.Color.White;
			switch (penColor)
			{
			case PenColor.PC_Red:
				return System.Drawing.Color.Red;
			case PenColor.PC_Blue:
				return System.Drawing.Color.Blue;
			case PenColor.PC_Green:
				return System.Drawing.Color.Green;
			case PenColor.PC_Gray:
				return System.Drawing.Color.Gray;
			case PenColor.PC_Yellow:
				return System.Drawing.Color.Yellow;
			case PenColor.PC_Black:
				return System.Drawing.Color.Black;
			case PenColor.PC_Lime:
				return System.Drawing.Color.Lime;
			case PenColor.PC_LightSkyBlue:
				return System.Drawing.Color.LightSkyBlue;
			case PenColor.PC_DarkCyan:
				return System.Drawing.Color.DarkCyan;
			}
			return System.Drawing.Color.White;
		}

		private float GetScale(Size size)
		{
			BoundingBoxUV boundingBox = this.GetBoundingBox();
			UV max = boundingBox.Max;
			UV min = boundingBox.Min;
			double num = (double)size.Width / (max.U - min.U);
			double num2 = (double)size.Height / (max.V - min.V);
			double num3 = (num <= num2) ? num : num2;
			return (float)num3;
		}

		private Transform ComputerTransMatrix(Size size)
		{
			Transform identity = Transform.Identity;
			identity.Origin = XYZ.Zero;
			identity.BasisX = XYZ.BasisX;
			identity.BasisY = -XYZ.BasisY;
			identity.BasisZ = XYZ.BasisZ;
			BoundingBoxUV boundingBox = this.GetBoundingBox();
			UV max = boundingBox.Max;
			UV min = boundingBox.Min;
			double num = (double)size.Width / (max.U - min.U);
			double num2 = (double)size.Height / (max.V - min.V);
			double num3 = (num <= num2) ? num : num2;
			Transform transform = Transform.Identity;
			transform = transform.ScaleBasis(num3);
			XYZ vector = new XYZ((min.U + max.U) / 2.0, (min.V + max.V) / 2.0, 0.0);
			Transform transform2 = RevitVersionFuncs.CreateTranslation(vector);
			Transform transform3 = Transform.Identity;
			transform3 = transform3.Multiply(identity.Inverse);
			transform3 = transform3.Multiply(transform);
			return transform3.Multiply(transform2.Inverse);
		}

		protected BoundingBoxUV GetBoundingBox()
		{
			BoundingBoxUV boundingBoxUV = null;
			List<EdgeInfo> list = new List<EdgeInfo>();
			foreach (CurveInfo curveInfo in this.m_Curves)
			{
				list.Add(new EdgeInfo(curveInfo.CurveObj));
			}
			foreach (FillRegion fillRegion in this.m_FillRegions)
			{
				list.AddRange(fillRegion.EdgeLoop);
			}
			foreach (EdgeInfo edgeInfo in list)
			{
				bool flag = Geometry.IsEqual(edgeInfo.Bulge, 0.0);
				if (flag)
				{
					bool flag2 = boundingBoxUV == null;
					if (flag2)
					{
						boundingBoxUV = Geometry.CalculateBoundingBox2D(edgeInfo.StartPoint, edgeInfo.EndPoint);
					}
					else
					{
						BoundingBoxUV box = Geometry.CalculateBoundingBox2D(edgeInfo.StartPoint, edgeInfo.EndPoint);
						boundingBoxUV = Geometry.BoundingBoxesMerge(boundingBoxUV, box);
					}
				}
				else
				{
					XYZ startPoint = edgeInfo.StartPoint;
					XYZ endPoint = edgeInfo.EndPoint;
					XYZ ptCenter = null;
					XYZ normal = XYZ.BasisZ;
					double radius = 0.0;
					double num = 0.0;
					double num2 = 0.0;
					Geometry.GetArcInfoWithBulge(startPoint, endPoint, edgeInfo.Bulge, ref ptCenter, ref radius, ref num, ref num2);
					bool flag3 = Geometry.LessThan(edgeInfo.Bulge, 0.0);
					if (flag3)
					{
						normal = -XYZ.BasisZ;
					}
					bool flag4 = boundingBoxUV == null;
					if (flag4)
					{
						boundingBoxUV = Geometry.CalculateBoundingBox2D(startPoint, endPoint, ptCenter, normal, radius);
					}
					else
					{
						BoundingBoxUV box2 = Geometry.CalculateBoundingBox2D(startPoint, endPoint, ptCenter, normal, radius);
						boundingBoxUV = Geometry.BoundingBoxesMerge(boundingBoxUV, box2);
					}
				}
			}
			foreach (TextNoteInfo textNoteInfo in this.m_TextNotes)
			{
				XYZ xyz = XYZ.BasisX * textNoteInfo.m_BoundingBoxWidth / 2.0;
				XYZ xyz2 = XYZ.BasisY * textNoteInfo.m_BoundingBoxHeight / 2.0;
				bool flag5 = textNoteInfo.m_AlignH == TextNoteInfo.AlignHType.AHT_Left;
				XYZ xyz3;
				if (flag5)
				{
					xyz3 = new XYZ(textNoteInfo.m_Position.X + textNoteInfo.m_BoundingBoxWidth / 2.0, textNoteInfo.m_Position.Y, textNoteInfo.m_Position.Z);
				}
				else
				{
					bool flag6 = textNoteInfo.m_AlignH == TextNoteInfo.AlignHType.AHT_Center;
					if (flag6)
					{
						xyz3 = textNoteInfo.m_Position;
					}
					else
					{
						xyz3 = new XYZ(textNoteInfo.m_Position.X - textNoteInfo.m_BoundingBoxWidth / 2.0, textNoteInfo.m_Position.Y, textNoteInfo.m_Position.Z);
					}
				}
				bool flag7 = textNoteInfo.m_AlignV == TextNoteInfo.AlignVType.AVT_Top;
				if (flag7)
				{
					xyz3 -= XYZ.BasisY * (textNoteInfo.m_BoundingBoxHeight / 2.0);
				}
				else
				{
					bool flag8 = textNoteInfo.m_AlignV == TextNoteInfo.AlignVType.AVT_Bottom;
					if (flag8)
					{
						xyz3 += XYZ.BasisY * (textNoteInfo.m_BoundingBoxHeight / 2.0);
					}
				}
				XYZ startPoint2 = xyz3 + xyz2 - xyz;
				XYZ endPoint2 = xyz3 - xyz2 + xyz;
				Line line = YJKLineEx.YJKGetBound(startPoint2, endPoint2);
				bool flag9 = boundingBoxUV == null;
				if (flag9)
				{
					boundingBoxUV = Geometry.CalculateBoundingBox2D(line);
				}
				else
				{
					BoundingBoxUV box3 = Geometry.CalculateBoundingBox2D(line);
					boundingBoxUV = Geometry.BoundingBoxesMerge(boundingBoxUV, box3);
				}
			}
			return boundingBoxUV;
		}

		protected void DrawLine(Pen pen, Line line, Transform trans)
		{
			XYZ xyz = line.GetEndPoint(0);
			XYZ xyz2 = line.GetEndPoint(1);
			xyz = Geometry.TransformPoint(xyz, trans);
			xyz2 = Geometry.TransformPoint(xyz2, trans);
			PointF pt = new PointF((float)xyz.X, (float)xyz.Y);
			PointF pt2 = new PointF((float)xyz2.X, (float)xyz2.Y);
			this.m_Graphics.DrawLine(pen, pt, pt2);
		}

		protected void DrawArc(Pen pen, Arc arc, Transform trans)
		{
			XYZ endPoint = arc.GetEndPoint(0);
			XYZ endPoint2 = arc.GetEndPoint(1);
			XYZ xyz = arc.Center;
			float num = (float)(arc.Radius * trans.Scale);
			XYZ normal = arc.Normal;
			double num2 = 0.0;
			double num3 = 0.0;
			Geometry.GetArcAngles(arc, ref num2, ref num3);
			float num4 = 6.28318548f - (float)num3;
			float num5 = 6.28318548f - (float)num2;
			bool flag = num4 > num5;
			if (flag)
			{
				num5 += 6.28318548f;
			}
			float num6 = num5 - num4;
			num4 = num4 * 180f / 3.14159274f;
			num6 = num6 * 180f / 3.14159274f;
			xyz = Geometry.TransformPoint(xyz, trans);
			float x = (float)(xyz.X - (double)num);
			float y = (float)(xyz.Y - (double)num);
			float num7 = num * 2f;
			this.m_Graphics.DrawArc(pen, x, y, num7, num7, num4, num6);
		}

		protected void DrawText(TextNoteInfo textNoteInfo, Transform trans)
		{
			bool flag = textNoteInfo.m_Text.CompareTo("") == 0;
			if (!flag)
			{
				float emSize = (float)(textNoteInfo.m_Height * trans.Scale);
				Font font = new Font("宋体", emSize);
				System.Drawing.Color color = this.PenColorToColor(textNoteInfo.m_Color);
				SolidBrush brush = new SolidBrush(color);
				XYZ xyz = Geometry.TransformPoint(textNoteInfo.m_Position, trans);
				double num = textNoteInfo.m_BoundingBoxWidth * trans.Scale;
				double num2 = textNoteInfo.m_BoundingBoxHeight * trans.Scale;
				bool flag2 = textNoteInfo.m_AlignH == TextNoteInfo.AlignHType.AHT_Left;
				double num3;
				if (flag2)
				{
					num3 = xyz.X;
				}
				else
				{
					bool flag3 = textNoteInfo.m_AlignH == TextNoteInfo.AlignHType.AHT_Center;
					if (flag3)
					{
						num3 = xyz.X - num / 2.0;
					}
					else
					{
						num3 = xyz.X - num;
					}
				}
				bool flag4 = textNoteInfo.m_AlignV == TextNoteInfo.AlignVType.AVT_Top;
				double num4;
				if (flag4)
				{
					num4 = xyz.Y;
				}
				else
				{
					bool flag5 = textNoteInfo.m_AlignV == TextNoteInfo.AlignVType.AVT_Middle;
					if (flag5)
					{
						num4 = xyz.Y - num2 / 2.0;
					}
					else
					{
						num4 = xyz.Y - num2;
					}
				}
				System.Drawing.Rectangle rect = new System.Drawing.Rectangle((int)num3, (int)num4, (int)num, (int)num2);
				StringFormat stringFormat = new StringFormat();
				stringFormat.LineAlignment = StringAlignment.Center;
				stringFormat.Alignment = StringAlignment.Center;
				bool flag6 = textNoteInfo.m_AlignH == TextNoteInfo.AlignHType.AHT_Left;
				XYZ xyz2;
				if (flag6)
				{
					xyz2 = new XYZ(xyz.X + num / 2.0, xyz.Y, xyz.Z);
					stringFormat.Alignment = StringAlignment.Near;
				}
				else
				{
					bool flag7 = textNoteInfo.m_AlignH == TextNoteInfo.AlignHType.AHT_Center;
					if (flag7)
					{
						xyz2 = xyz;
						stringFormat.Alignment = StringAlignment.Center;
					}
					else
					{
						xyz2 = new XYZ(xyz.X - num / 2.0, xyz.Y, xyz.Z);
						stringFormat.Alignment = StringAlignment.Far;
					}
				}
				bool flag8 = textNoteInfo.m_AlignV == TextNoteInfo.AlignVType.AVT_Top;
				if (flag8)
				{
					xyz2 -= XYZ.BasisY * (num2 / 2.0);
					stringFormat.LineAlignment = StringAlignment.Far;
				}
				else
				{
					bool flag9 = textNoteInfo.m_AlignV == TextNoteInfo.AlignVType.AVT_Bottom;
					if (flag9)
					{
						xyz2 += XYZ.BasisY * (num2 / 2.0);
						stringFormat.LineAlignment = StringAlignment.Center;
					}
					else
					{
						stringFormat.LineAlignment = StringAlignment.Near;
					}
				}
				Matrix matrix = new Matrix();
				double num5 = textNoteInfo.m_Angle * 180.0 / Math.PI;
				matrix.RotateAt((float)num5, new PointF((float)xyz2.X, (float)xyz2.Y));
				Matrix transform = this.m_Graphics.Transform;
				Matrix transform2 = this.m_Graphics.Transform;
				transform2.Multiply(matrix);
				this.m_Graphics.Transform = transform2;
				this.m_Graphics.FillEllipse(Brushes.White, rect);
				this.m_Graphics.DrawString(textNoteInfo.m_Text, font, brush, (float)rect.Left, (float)rect.Top, stringFormat);
				this.m_Graphics.Transform = transform;
			}
		}

		private void DrawFillRegion(FillRegion fillRegion, Transform trans)
		{
			try
			{
				List<EdgeInfo> edgeLoop = fillRegion.EdgeLoop;
				List<XYZ> list = new List<XYZ>();
				List<double> list2 = new List<double>();
				double num = 0.0;
				for (int i = 0; i < edgeLoop.Count; i++)
				{
					EdgeInfo edgeInfo = edgeLoop[i];
					num += edgeInfo.Length();
					list.Add(edgeInfo.StartPoint);
					list2.Add(edgeInfo.Bulge);
				}
				double fitSpace = num / (double)edgeLoop.Count / 10.0;
				List<XYZ> list3 = new List<XYZ>();
				Geometry.GetFittingPolyline(list, list2, ref list3, fitSpace);
				for (int i = 0; i < list3.Count; i++)
				{
					list3[i] = Geometry.TransformPoint(list3[i], trans);
				}
				GraphicsPath graphicsPath = new GraphicsPath();
				for (int i = 0; i < list3.Count; i++)
				{
					XYZ xyz = list3[i];
					bool flag = i == list3.Count - 1;
					XYZ xyz2;
					if (flag)
					{
						xyz2 = list3[0];
					}
					else
					{
						xyz2 = list3[i + 1];
					}
					graphicsPath.AddLine((float)xyz.X, (float)xyz.Y, (float)xyz2.X, (float)xyz2.Y);
				}
				Brush brush = new SolidBrush(this.PenColorToColor(fillRegion.Color));
				this.m_Graphics.FillRegion(brush, new Region(graphicsPath));
			}
			catch (Exception)
			{
			}
		}

		private List<CurveInfo> m_Curves = new List<CurveInfo>();

		private List<TextNoteInfo> m_TextNotes = new List<TextNoteInfo>();

		private List<FillRegion> m_FillRegions = new List<FillRegion>();

		private Graphics m_Graphics;

		private System.Windows.Forms.Control m_Control;
	}
}
